package com.dhcc.core.framework.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import com.dhcc.core.framework.exception.BizException;
import com.dhcc.core.framework.util.codec.EncodeUtil;

/**
 * 文件工具类
 * 
 * @ClassName: FileUtil
 * @Description: TODO
 * @author: cyf
 * @date: 2018年1月2日 上午9:34:45
 */
public class FileUtil extends org.apache.commons.io.FileUtils {

    private static final Logger log = LoggerFactory.getLogger(FileUtil.class);

    /**
     * 获取文件分隔符
     * 
     * @return 返回系统对应的分隔符
     */
    public static String getFileSeparator() {
        return System.getProperty("file.separator");
    }

    /**
     * 修正路径，将 \\ 或 / 等替换为 File.separator
     * @param path 待修正的路径
     * @return 修正后的路径
     */
    public static String path(String path){
        String p = StringUtils.replace(path, "\\", "/");
        p = StringUtils.join(StringUtils.split(p, "/"), "/");
        if (!StringUtils.startsWithAny(p, "/") && StringUtils.startsWithAny(path, "\\", "/")){
            p += "/";
        }
        if (!StringUtils.endsWithAny(p, "/") && StringUtils.endsWithAny(path, "\\", "/")){
            p = p + "/";
        }
        if (path != null && path.startsWith("/")){
            p = "/" + p; // linux下路径
        }
        return p;
    }
    /**
     * 获取文件扩展名
     * 
     * @param filename
     * @return
     */
    public static String getExtensionName(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot > -1) && (dot < (filename.length() - 1))) {
                return filename.substring(dot + 1);
            }
        }
        return filename;
    }

    /**
     * NIO way
     */
    public static byte[] toByteArray(String filename) {

        File f = new File(filename);
        if (!f.exists()) {
            log.error("文件未找到！" + filename);
            throw new BizException("文件未找到！");
        }
        FileChannel channel = null;
        FileInputStream fs = null;
        try {
            fs = new FileInputStream(f);
            channel = fs.getChannel();
            ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
            while ((channel.read(byteBuffer)) > 0) {
                // do nothing
                // System.out.println("reading");
            }
            return byteBuffer.array();
        } catch (IOException e) {
            throw new BizException("文件读取错误！");
        } finally {
            try {
                channel.close();
            } catch (IOException e) {
                throw new BizException("文件读取错误！");
            }
            try {
                fs.close();
            } catch (IOException e) {
                throw new BizException("文件读取错误！");
            }
        }
    }

    /**
     * 递归删除文件夹文件
     * 
     * @param file
     */
    public static void deleteFile(File file) {
        if (file.exists()) {// 判断文件是否存在
            if (file.isFile()) {// 判断是否是文件
                file.delete();// 删除文件
            } else if (file.isDirectory()) {// 否则如果它是一个目录
                File[] files = file.listFiles();// 声明目录下所有的文件 files[];
                for (int i = 0; i < files.length; i++) {// 遍历目录下所有的文件
                    deleteFile(files[i]);// 把每个文件用这个方法进行迭代
                }
                file.delete();// 删除文件夹
            }
        }
    }

    /**
     * 读取文件内容
     * 
     * @param filePath
     * @param isLine
     *            是否换行符
     * @return 返回读取到的字符串
     */
    public static String readFile(String filePath, boolean isLine) {
        StringBuffer content = null;
        if (CommonUtil.isNotEmpty(filePath)) {
            File file = new File(filePath);
            if (!file.exists()) {
                log.error("文件不存在[" + filePath + "]");
            } else {
                try {
                    BufferedReader buffReader = new BufferedReader(
                            new InputStreamReader(new FileInputStream(file), "UTF-8"));
                    String line = null;
                    content = new StringBuffer();
                    while ((line = buffReader.readLine()) != null) {
                        if (isLine) {
                            line = line + "\n";
                        }
                        content.append(line);
                    }
                    buffReader.close();
                    buffReader = null;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        } else {
            log.error("文件路径为空");
        }
        return (null == content) ? null : content.toString();
    }

    /**
     * 内容写入到文件
     * 
     * @param contents
     * @param filePath
     * @param cover
     *            如果文件存在，是否覆盖
     * @return 写入成功返回：true；否则返回：false
     */
    public static boolean writeFile(String contents, String filePath, boolean cover) {
        boolean is = false;
        if (CommonUtil.isNotEmpty(filePath) && CommonUtil.isNotEmpty(contents)) {
            File file = new File(filePath);
            if (file.exists()) {
                log.error("文件已存在[" + filePath + "]");
                if (cover)
                    file.delete();
                else
                    return is;
            }
            File dir = file.getParentFile();
            if (!dir.exists()) {
                dir.mkdirs();
            }
            try {
                BufferedWriter buffWriter = new BufferedWriter(
                        new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8"));
                buffWriter.write(contents);
                buffWriter.flush();
                buffWriter.close();
                is = true;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            log.error("文件路径或内容为空");
        }
        return is;
    }

    /**
     * 内容写入到文件中
     * 
     * @param filePath
     * @param contents
     * @return 写入成功返回：true；否则返回：false
     */
    public static boolean writeFile(String filePath, String contents) {
        boolean is = false;
        if (CommonUtil.isNotEmpty(filePath)) {
            File file = new File(filePath);
            if (null != file && file.exists()) {
                try {
                    BufferedWriter writer = new BufferedWriter(
                            new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
                    writer.write(contents);
                    writer.flush();
                    writer.close();
                    is = true;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                log.error("文件不存在[" + file.getAbsolutePath() + "]");
            }
        }
        return is;
    }

    /**
     * 内容写入到文件中
     * 
     * @param file
     * @param contents
     * @return 写入成功返回：true；否则返回：false
     */
    public static boolean writeFile(File file, String contents) {
        boolean is = false;
        if (null != file && file.exists()) {
            try {
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
                writer.write(contents);
                writer.flush();
                writer.close();
                is = true;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            log.error("文件不存在[" + file.getAbsolutePath() + "]");
        }
        return is;
    }
    /**
     * 根据图片Base64写入图片文件
     * @param fileName 写入的文件路径及文件名
     * @param imageBase64 图片Base64字符串
     */
    public static void writeToFileByImageBase64(String fileName, String imageBase64){
        String base64 = StringUtils.substringAfter(imageBase64, "base64,");
        if (StringUtils.isBlank(base64)){
            return;
        }
        byte[] data = EncodeUtil.decodeBase64(base64);
        
        File file = new File(fileName);
        try {
            FileUtil.writeByteArrayToFile(file, data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * @Description: 在页面接受多个文件上传
     * @Title: uploadFiles   
     * @param files 多文件集合
     * @param filePath 文件保存位置
     * @return: void      
     * @author: wujiafeng
     * @date:2020年3月26日 下午4:18:11
     */
    public static void uploadFiles(MultipartFile[] files,String filePath){
		 //判断文件夹是否存在
        File file=new File(filePath);
		if(!file.exists()){
            //创建文件夹
            file.mkdirs();
        }
		if(!filePath.endsWith(File.separator)){
 		   filePath += File.separator;
		}
		 //批量上传
        for(int i = 0;i<files.length;i++){  
            if(!files[i].getOriginalFilename().isEmpty()){
                String path = filePath+files[i].getOriginalFilename();
                File newFile=new File(path);
                try {
                	//开始上传文件
//                    files[i].transferTo(newFile);
                    FileUtils.copyInputStreamToFile(files[i].getInputStream(),newFile);
                } catch (IllegalStateException | IOException e){
                    e.printStackTrace();
                }
            }
         }
    }
    
    /**
     * @Description: 下载文件
     * @Title: downFile   
     * @param filePath
     * @param fileName
     * @param resp 
     * @return: void      
     * @author: wujiafeng
     * @date:2020年3月27日 上午10:57:52
     */
    public static void downFile(String filePath,String fileName,HttpServletResponse resp){
    	if(!filePath.endsWith(File.separator)){
    		filePath += File.separator;
    	}
    	String tempPath  = filePath+fileName;
        File file = new File(tempPath);
	    if(file.exists()){
			try {
				//将文件名设置为中文
				byte[] tmpb = file.getName().toString().getBytes("GBK");
				String fileNameCN = new String(tmpb, "8859_1"); 
		    	resp.setContentType("application/octet-stream");
			    resp.setHeader("Content-Disposition","attachment;filename=" + fileNameCN);
			    resp.setContentLength((int) file.length());
			    //打开指定文件流
				BufferedInputStream fileInputStream = new BufferedInputStream(new FileInputStream(tempPath));
				//写出流信息
				byte[] bytes =new byte[1024];
				OutputStream os = resp.getOutputStream();
				BufferedOutputStream fosObject = new BufferedOutputStream(os);
				while (fileInputStream.read(bytes)!=-1) {
					fosObject.write(bytes);
				}
				fileInputStream.close();
				fosObject.close();
				os.flush();
				os.close();
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
	    }
    }
}
